(function (window, T) {
    var string = T.string = {};
    /**
     * 删除目标字符串两端的空白字符
     * @name string.trim
     * @function
     * @grammar string.trim(source)
     * @param {string} source 目标字符串
     * @remark
     * 不支持删除单侧空白字符
     * @shortcut trim
     * @meta standard
     *             
     * @returns {string} 删除两端空白字符后的字符串
     */
    (function () {
        var trimer = new RegExp("(^[\\s\\t\\xa0\\u3000]+)|([\\u3000\\xa0\\s\\t]+\x24)", "g");     
        string.trim = function (source) {
            return String(source).replace(trimer, "");
        };
    })();

    /**
     * 对目标字符串进行html解码
     * @name string.decodeHTML
     * @function
     * @grammar string.decodeHTML(source)
     * @param {string} source 目标字符串
     * @shortcut decodeHTML
     * @meta standard
     * @see string.encodeHTML
     *             
     * @returns {string} html解码后的字符串
     */
    string.decodeHTML = function (source) {
        var str = String(source)
                    .replace(/&quot;/g,'"')
                    .replace(/&lt;/g,'<')
                    .replace(/&gt;/g,'>')
                    .replace(/&amp;/g, "&");
        //处理转义的中文和实体字符
        return str.replace(/&#([\d]+);/g, function(_0, _1){
            return String.fromCharCode(parseInt(_1, 10));
        });
    };

    /**
     * 对目标字符串进行html编码
     * @name string.encodeHTML
     * @function
     * @grammar string.encodeHTML(source)
     * @param {string} source 目标字符串
     * @remark
     * 编码字符有5个：&<>"'
     * @shortcut encodeHTML
     * @meta standard
     * @see string.decodeHTML
     *             
     * @returns {string} html编码后的字符串
     */
    string.encodeHTML = function (source) {
        return String(source)
                    .replace(/&/g,'&amp;')
                    .replace(/</g,'&lt;')
                    .replace(/>/g,'&gt;')
                    .replace(/"/g, "&quot;")
                    .replace(/'/g, "&#39;");
    };
    /**
     * 对目标字符串进行格式化
     * @name string.format
     * @function
     * @grammar string.format(source, opts)
     * @param {string} source 目标字符串
     * @param {Object|string...} opts 提供相应数据的对象或多个字符串
     * @remark
     * 
    opts参数为“Object”时，替换目标字符串中的#{property name}部分。<br>
    opts为“string...”时，替换目标字符串中的#{0}、#{1}...部分。
            
     * @shortcut format
     * @meta standard
     *             
     * @returns {string} 格式化后的字符串
     */
    string.format = function (source, opts) {
        source = String(source);
        var data = Array.prototype.slice.call(arguments,1), toString = Object.prototype.toString;
        if(data.length){
            data = data.length == 1 ? 
                /* ie 下 Object.prototype.toString.call(null) == '[object Object]' */
                (opts !== null && (/\[object Array\]|\[object Object\]/.test(toString.call(opts))) ? opts : data) 
                : data;
            return source.replace(/#\{(.+?)\}/g, function (match, key){
                var replacer = data[key];
                // chrome 下 typeof /a/ == 'function'
                if('[object Function]' == toString.call(replacer)){
                    replacer = replacer(key);
                }
                return ('undefined' == typeof replacer ? '' : replacer);
            });
        }
        return source;
    };

    /**
     * 获取目标字符串在gbk编码下的字节长度
     * @name string.getByteLength
     * @function
     * @grammar string.getByteLength(source)
     * @param {string} source 目标字符串
     * @remark
     * 获取字符在gbk编码下的字节长度, 实现原理是认为大于127的就一定是双字节。如果字符超出gbk编码范围, 则这个计算不准确
     * @meta standard
     * @see string.subByte
     *             
     * @returns {number} 字节长度
     */
    string.getByteLength = function (source) {
        return String(source).replace(/[^\x00-\xff]/g, "ci").length;
    };

    /**
     * 去掉字符串中的html标签
     * @function
     * @grammar string.stripTags(source)
     * @param {string} source 要处理的字符串.
     * @return {String}
     */
    string.stripTags = function(source) {
        return String(source || '').replace(/<[^>]+>/g, '');
    };

    /**
     * 对目标字符串按gbk编码截取字节长度
     * @name string.subByte
     * @function
     * @grammar string.subByte(source, length)
     * @param {string} source 目标字符串
     * @param {number} length 需要截取的字节长度
     * @param {string} [tail] 追加字符串,可选.
     * @remark
     * 截取过程中，遇到半个汉字时，向下取整。
     * @see string.getByteLength
     *             
     * @returns {string} 字符串截取结果
     */
    string.subByte = function (source, length, tail) {
        source = String(source);
        tail = tail || '';
        if (length < 0 || string.getByteLength(source) <= length) {
            return source + tail;
        }
        
        //thanks 加宽提供优化方法
        source = source.substr(0,length).replace(/([^\x00-\xff])/g,"\x241 ")//双字节字符替换成两个
            .substr(0,length)//截取长度
            .replace(/[^\x00-\xff]$/,"")//去掉临界双字节字符
            .replace(/([^\x00-\xff]) /g,"\x241");//还原
        return source + tail;

    };

    /**
     * 将目标字符串中常见全角字符转换成半角字符
     * @name string.toHalfWidth
     * @function
     * @grammar string.toHalfWidth(source)
     * @param {string} source 目标字符串
     * @remark
     * 
    将全角的字符转成半角, 将“&amp;#xFF01;”至“&amp;#xFF5E;”范围的全角转成“&amp;#33;”至“&amp;#126;”, 还包括全角空格包括常见的全角数字/空格/字母, 用于需要同时支持全半角的转换, 具体转换列表如下("空格"未列出)：<br><br>

    ！ => !<br>
    ＂ => "<br>
    ＃ => #<br>
    ＄ => $<br>
    ％ => %<br>
    ＆ => &<br>
    ＇ => '<br>
    （ => (<br>
    ） => )<br>
    ＊ => *<br>
    ＋ => +<br>
    ， => ,<br>
    － => -<br>
    ． => .<br>
    ／ => /<br>
    ０ => 0<br>
    １ => 1<br>
    ２ => 2<br>
    ３ => 3<br>
    ４ => 4<br>
    ５ => 5<br>
    ６ => 6<br>
    ７ => 7<br>
    ８ => 8<br>
    ９ => 9<br>
    ： => :<br>
    ； => ;<br>
    ＜ => <<br>
    ＝ => =<br>
    ＞ => ><br>
    ？ => ?<br>
    ＠ => @<br>
    Ａ => A<br>
    Ｂ => B<br>
    Ｃ => C<br>
    Ｄ => D<br>
    Ｅ => E<br>
    Ｆ => F<br>
    Ｇ => G<br>
    Ｈ => H<br>
    Ｉ => I<br>
    Ｊ => J<br>
    Ｋ => K<br>
    Ｌ => L<br>
    Ｍ => M<br>
    Ｎ => N<br>
    Ｏ => O<br>
    Ｐ => P<br>
    Ｑ => Q<br>
    Ｒ => R<br>
    Ｓ => S<br>
    Ｔ => T<br>
    Ｕ => U<br>
    Ｖ => V<br>
    Ｗ => W<br>
    Ｘ => X<br>
    Ｙ => Y<br>
    Ｚ => Z<br>
    ［ => [<br>
    ＼ => \<br>
    ］ => ]<br>
    ＾ => ^<br>
    ＿ => _<br>
    ｀ => `<br>
    ａ => a<br>
    ｂ => b<br>
    ｃ => c<br>
    ｄ => d<br>
    ｅ => e<br>
    ｆ => f<br>
    ｇ => g<br>
    ｈ => h<br>
    ｉ => i<br>
    ｊ => j<br>
    ｋ => k<br>
    ｌ => l<br>
    ｍ => m<br>
    ｎ => n<br>
    ｏ => o<br>
    ｐ => p<br>
    ｑ => q<br>
    ｒ => r<br>
    ｓ => s<br>
    ｔ => t<br>
    ｕ => u<br>
    ｖ => v<br>
    ｗ => w<br>
    ｘ => x<br>
    ｙ => y<br>
    ｚ => z<br>
    ｛ => {<br>
    ｜ => |<br>
    ｝ => }<br>
    ～ => ~<br>
            
     *             
     * @returns {string} 转换后的字符串
     */

    string.toHalfWidth = function (source) {
        return String(source).replace(/[\uFF01-\uFF5E]/g, 
            function(c){
                return String.fromCharCode(c.charCodeAt(0) - 65248);
            }).replace(/\u3000/g," ");
    };

    /**
     * 将目标字符串中可能会影响正则表达式构造的字符串进行转义。
     * @name string.escapeReg
     * @function
     * @grammar string.escapeReg(source)
     * @param {string} source 目标字符串
     * @remark
     * 给以下字符前加上“\”进行转义：.*+?^=!:${}()|[]/\
     * @meta standard
     *             
     * @returns {string} 转义后的字符串
     */
    string.escapeReg = function (source) {
        return String(source)
                .replace(new RegExp("([.*+?^=!:\x24{}()|[\\]\/\\\\])", "g"), '\\\x241');
    };


})(window, T);